-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🌱 Add NamingStrategy to KubeadmControlPlane #11123
base: main
Are you sure you want to change the base?
🌱 Add NamingStrategy to KubeadmControlPlane #11123
Conversation
Skipping CI for Draft Pull Request. |
right now it only has API changes, and the remaining work is in progress, I opened a draft PR so I can get some early inputs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested some changes. Let me know what you think
controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_types.go
Outdated
Show resolved
Hide resolved
controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_types.go
Outdated
Show resolved
Hide resolved
0b403b1
to
9aa9eb9
Compare
@@ -228,6 +233,19 @@ type RemediationStrategy struct { | |||
MinHealthyPeriod *metav1.Duration `json:"minHealthyPeriod,omitempty"` | |||
} | |||
|
|||
// MachineNamingStrategy defines the naming strategy for control plane objects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// MachineNamingStrategy defines the naming strategy for control plane objects. | |
// MachineNamingStrategy allows changing the naming pattern used when creating Machines. | |
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines. |
lgtm for the API from my side (+/- the godoc nit) Before I start to review the implementation, @fabriziopandini @chrischdi @mdbooth @lentzi90 Are we fine with the API and does it cover your use cases? |
@adilGhaffarDev is representing the interests of @lentzi90 while he's away. From my POV, I'm happy if @adilGhaffarDev thinks it covers the use case. |
9aa9eb9
to
85183ee
Compare
@lentzi90 flag was also for machineset and that is also going to be removed after 1.9, can I add same namingStrategy in MchineDeployments too in this same PR? |
I will open separate PR for MDs, as discussed here: #10577 (comment) , @sbueringer please review this one. Also, fuzzing tests are failing in |
85183ee
to
3f44bac
Compare
I would like to get reviews from other maintainers on the API first. It's not only my call. |
@@ -117,6 +117,11 @@ type KubeadmControlPlaneSpec struct { | |||
// The RemediationStrategy that controls how control plane machine remediation happens. | |||
// +optional | |||
RemediationStrategy *RemediationStrategy `json:"remediationStrategy,omitempty"` | |||
|
|||
// MachineNamingStrategy allows changing the naming pattern used when creating Machines. | |||
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines. | |
// InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines. |
there is no need for the Note:
here. this is just another sentence providing the additional context.
@@ -228,6 +233,20 @@ type RemediationStrategy struct { | |||
MinHealthyPeriod *metav1.Duration `json:"minHealthyPeriod,omitempty"` | |||
} | |||
|
|||
// MachineNamingStrategy allows changing the naming pattern used when creating Machines. | |||
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Note: InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines. | |
// InfraMachines & KubeadmConfigs will use the same name as the corresponding Machines. |
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object. | ||
// * `.random`: A random alphanumeric string, without vowels, of length 5. | ||
// +optional | ||
Template *string `json:"template,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there benefits of having this as a pointer field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, just a mistake I copied from somewhere else. Fine to drop the pointer
if kcp.Spec.MachineNamingStrategy != nil && kcp.Spec.MachineNamingStrategy.Template != nil { | ||
nameTemplate = *kcp.Spec.MachineNamingStrategy.Template | ||
} | ||
generatedMachineName, err := topologynames.KCPMachineNameGenerator(nameTemplate, kcp.Name).GenerateName() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will
get concatenated with a random suffix of length 5.
should there be an explicit test case for this on the MachineNamingStrategy level?
presumably https://github.com/kubernetes-sigs/cluster-api/blob/90c4712f67bf21fce52e07a57488f62497306699/internal/topology/names/names.go#L40C30-L40C43 has tests, but might be worth testing on this level too.
3f44bac
to
61f19f1
Compare
3ac0057
to
c5e36b8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
LGTM label has been added. Git tree hash: 8c506758c47f4cf2c10dbc19e12c368095531f1f
|
/hold |
@fabriziopandini @chrischdi please take a look when you get time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change lgtm to me (just nits & minor improvements).
@JoelSpeed @vincepri for a quick look at the API changes
type MachineNamingStrategy struct { | ||
// Template defines the template to use for generating the names of the Machine objects. | ||
// If not defined, it will fallback to `{{ .kubeadmcontrolplane.name }}-{{ .random }}`. | ||
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will | |
// If the generate name string exceeds 63 characters, it will be trimmed to 58 characters and will |
I assume
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will | ||
// get concatenated with a random suffix of length 5. | ||
// The templating mechanism provides the following arguments: | ||
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should provide also cluster name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay for me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added clustername too.
want []gomegatypes.GomegaMatcher | ||
}{ | ||
{ | ||
name: "should return the correct Machine object when creating a new Machine", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a test case for the default behaviour (no template) and for when the generated name exceeds the lenght
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, following cases are added:
- User-defined template
- template exceeding 63 chars.
- invalid template
- no template
We are already testing some cases here: https://github.com/kubernetes-sigs/cluster-api/blob/main/internal/topology/names/names_test.go
}, | ||
}, | ||
MachineNamingStrategy: &controlplanev1.MachineNamingStrategy{ | ||
Template: fmt.Sprintf("%064d", 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
Template: fmt.Sprintf("%064d", 0), | |
Template: fmt.Sprintf("%064d", 0), // invalid template |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was not invalid; the test was named wrong and is now fixed.
I have added a new test with an invalid template too.
type MachineNamingStrategy struct { | ||
// Template defines the template to use for generating the names of the Machine objects. | ||
// If not defined, it will fallback to `{{ .kubeadmcontrolplane.name }}-{{ .random }}`. | ||
// If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the combination of the name and random suffix is 64 characters? Do we then trim and add a new random suffix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
if len(name) > maxNameLength {
name = name[:maxGeneratedNameLength] + utilrand.String(randomLength)
}
(maxNameLength is 63)
// get concatenated with a random suffix of length 5. | ||
// The templating mechanism provides the following arguments: | ||
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object. | ||
// * `.random`: A random alphanumeric string, without vowels, of length 5. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why expose this rather than always appending -<random 5 chars>
at the end of the string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the following reasons:
- We already have namingStrategies in the ClusterClass that work the same way as the one introduced here (so consistency would be nice)
- In that case we use the namingStrategies to calculate control plane / MD and MP names. In these cases it was desirable to not always end up with a random suffix. E.g. folks wanted to be able to have KCP names that are identical to Cluster names
- Another case would be if folks have the (admittedly strange) use case that the random part shouldn't be at the end of the name (there was one (!) person asking for it in Slack, they wanted a random prefix for some reason, xref: https://kubernetes.slack.com/archives/C8TSNPY4T/p1724389852680579)
// The templating mechanism provides the following arguments: | ||
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that bullet points look great here, but the formatting does not transfer well to kubectl explain
, review the CRD description of this field and you'll see the formatting is all squashed. Instead, use full sentences to explain the same context.
Something along the lines of
// The template allows the following variables ".kubadmcontrolplane.name", ".something.else" and ".random".
// The variable ".kubeadmcontrolplane.name" retrieves the name of the KubeadmControlPlane object that owns the Machines being created.
// The variable ".random" is substituted with a 5 character alphanumeric string on creation.
// Variables in the template must be enclosed in double braces ("{{ <variable> }}").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object. | ||
// * `.random`: A random alphanumeric string, without vowels, of length 5. | ||
// +optional | ||
Template string `json:"template,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should impose a maximal length on this string, you know that the rendered value must not exceed 63 chars, so it needs to be at least that in length, assuming a worst case, the value of any substituted variable could be 1 character right?
So it needs to be 62 plus the length in the template of representing the longest variable. Currently that is {{ .kubeadmcontrolplane.name }}
which is 31 characters, so, a limit of 93 would be suitable presently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can do this slightly better and easier. We already have similar validation for the other namingStrategies we have:
cluster-api/internal/webhooks/clusterclass.go
Line 437 in 8752f4f
name, err := names.ControlPlaneNameGenerator(*clusterClass.Spec.ControlPlane.NamingStrategy.Template, "cluster").GenerateName() |
So we can verify:
- that the template actually renders
- that the rendered output is a valid name
- use the minimal length for our parameters and then check if the generated output is too long
- Not sure if we actually ever hit that case, because we have that safeguard that we just cut if rendered string gets too long. So I think we don't need this validation?
- Note: You can do a bunch of stuff in templates, so I think the template can be a lot longer without actually leading to long rendered values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I am a bit confused, do we need restrictions on minimum chars too for the generated name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JoelSpeed wdyt based on my comment above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that sounds reasonable yes! So that would be webhook based validation, you should still also include an API side maximum length though (since we can calculate a reasonable maximum)
Having maximum lengths on all fields is good practice and helps with the runtime cost analysis that's built into the CEL libraries, should we ever get to using those.
You can add length limits when the API is introduced, restricting them later is harder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, good point. I forgot the CEL part
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The validation webhook that is in clusterclass I believe is checking all the things needed. I have added the same here, let me know if anything needs to be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see that the webhook is checking the template, but, I think we do still want to have a length limit as a marker on the API field here, for completeness
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added the marker for max length please check.
// * `.kubeadmcontrolplane.name`: The name of the KubeadmControlPlane object. | ||
// * `.random`: A random alphanumeric string, without vowels, of length 5. | ||
// +optional | ||
Template string `json:"template,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to impose a pattern validation on this string?
Is there any admission time validation at present that checks that this compiles and would produce a valid template?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
(I didn't review the implementation myself yet, only the API)
We should have a similar validation than what we have for other naming strategies:
cluster-api/internal/webhooks/clusterclass.go
Line 437 in 8752f4f
name, err := names.ControlPlaneNameGenerator(*clusterClass.Spec.ControlPlane.NamingStrategy.Template, "cluster").GenerateName() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added the validation webhook, please check.
c5e36b8
to
7faf0d3
Compare
New changes are detected. LGTM label has been removed. |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
f316bd3
to
9049aaa
Compare
Signed-off-by: Muhammad Adil Ghaffar <muhammad.adil.ghaffar@est.tech>
9049aaa
to
94c96ca
Compare
@adilGhaffarDev: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
@sbueringer fuzz tests for v1alpha are failing, what do I need to add to fix these tests? |
What this PR does / why we need it:
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes part of #10577